
package com.yuanchuang.yp.mall.web.admin.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yuanchuang.yp.framework.common.FsBeanUtil;
import com.yuanchuang.yp.framework.common.exception.BaseException;
import com.yuanchuang.yp.mall.web.admin.common.enums.AccountTypeEnum;
import com.yuanchuang.yp.mall.web.admin.common.exception.AccountException;
import com.yuanchuang.yp.mall.web.admin.common.utils.AesEncodeUtil;
import com.yuanchuang.yp.mall.web.admin.entity.AuthMenuDO;
import com.yuanchuang.yp.mall.web.admin.entity.AuthRoleMenuRelDO;
import com.yuanchuang.yp.mall.web.admin.entity.AuthRoleUserRelDO;
import com.yuanchuang.yp.mall.web.admin.entity.AuthUserDO;
import com.yuanchuang.yp.mall.web.admin.user.mapper.AuthMenuMapper;
import com.yuanchuang.yp.mall.web.admin.user.mapper.AuthRoleMenuRelMapper;
import com.yuanchuang.yp.mall.web.admin.user.mapper.AuthRoleUserRelMapper;
import com.yuanchuang.yp.mall.web.admin.user.mapper.AuthUserMapper;
import com.yuanchuang.yp.mall.web.admin.user.model.LoginModel;
import com.yuanchuang.yp.mall.web.admin.user.model.LoginRequest;
import com.yuanchuang.yp.mall.web.admin.user.model.MenuModel;
import com.yuanchuang.yp.mall.web.admin.user.model.TreeMenuModel;
import com.yuanchuang.yp.mall.web.admin.user.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;

/**
 * meiguang8.com
 * Copyright (C) 2016-2019 All Rights Reserved.
 */

/**
 * class_name: AuthServiceImpl
 * package: com.yuanchuang.yp.mall.web.admin.service
 * describe: TODO
 * @author: yuanyuan.zhu
 * creat_date: 2019/7/11
 * creat_time: 15:29
 **/
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthUserMapper authUserMapper;
    @Autowired
    private AuthMenuMapper authMenuMapper;
    @Autowired
    private AuthRoleMenuRelMapper authRoleMenuRelMapper;

    @Autowired
    private AuthRoleUserRelMapper authRoleUserRelMapper;

    /**
     * 获取用户所属的菜单
     *
     * @param authUserId
     * @return
     */
    @Override
    public List<MenuModel> listMenus(Long authUserId) {
        List<AuthMenuDO> menuModels = authMenuMapper.listMenus(authUserId);
        return FsBeanUtil.convertList(menuModels, MenuModel.class);
    }

    /**
     * 获取用户所属的菜单 tree
     *
     * @param authUserId
     * @return
     */
    @Override
    public List<TreeMenuModel> listMenuTree(Long authUserId) {
        List<AuthRoleUserRelDO> authRoleMenuRelDOS = authRoleUserRelMapper.listAuthRoleByAuthUserId(authUserId);
        List<Long> roles = authRoleMenuRelDOS.stream().
                map(authRoleMenuRelDO -> authRoleMenuRelDO.getAuthRoleId())
                .collect(Collectors.toList());
        List<AuthRoleMenuRelDO> authRoleMenuRelDOS1 = authRoleMenuRelMapper.selectList(Wrappers.<AuthRoleMenuRelDO>lambdaQuery().in(AuthRoleMenuRelDO::getAuthRoleId, roles.toArray()));
        List<Long> menus = authRoleMenuRelDOS1.stream()
                .map(value -> value.getAuthMenuId())
                .collect(Collectors.toList());
        List<AuthMenuDO> authMenuDOS = authMenuMapper.selectBatchIds(menus);
        Map<Integer, List<AuthMenuDO>> listMap = authMenuDOS.stream().collect(groupingBy(AuthMenuDO::getParentId));
        List<AuthMenuDO> authMenuDOS1 = listMap.get(0);
        TreeMenuModel target;
        List<TreeMenuModel> treeMenuModels = new ArrayList<>();
        TreeMenuModel.TreeMenuMeta meta;
        for (AuthMenuDO authMenuDO : authMenuDOS1) {
            List<TreeMenuModel>    children = new ArrayList<>();
            List<AuthMenuDO> authMenuDOS2 = listMap.get(Math.toIntExact(authMenuDO.getId()));
            target = new TreeMenuModel();
            FsBeanUtil.copy(authMenuDO, target);
            meta = new TreeMenuModel.TreeMenuMeta();
            meta.setTitle(target.getName());
            target.setMeta(meta);
            target.setMenuId(authMenuDO.getId());
            authMenuDOS2.forEach(authMenuDO1 -> {
                TreeMenuModel target1 = new TreeMenuModel();
                FsBeanUtil.copy(authMenuDO1, target1);
                TreeMenuModel.TreeMenuMeta meta1 = new TreeMenuModel.TreeMenuMeta();
                meta1.setTitle(target1.getName());
                target1.setMeta(meta1);
                target1.setMenuId(authMenuDO1.getId());
                children.add(target1);
            });
            target.setChildren(children);
            treeMenuModels.add(target);
        }
        return treeMenuModels;
    }

    /**
     * 登陆
     *
     * @param loginRequest
     * @return
     */
    @Override
    public LoginModel login(LoginRequest loginRequest) throws BaseException {
        Integer type = loginRequest.getType();
        AccountTypeEnum accountTypeEnum = AccountTypeEnum.getByValue(type);
        if (null == accountTypeEnum) {
            throw new AccountException("1111", "账号类型不匹配-type=[{0}]", loginRequest.getType());
        }
        AuthUserDO authUserDO = new AuthUserDO();
        LambdaQueryWrapper<AuthUserDO> queryWrapper = Wrappers.<AuthUserDO>lambdaQuery();
        switch (accountTypeEnum) {
            case EMAIL:
                queryWrapper.eq(AuthUserDO::getEmail, loginRequest.getAccount());
                queryWrapper.eq(AuthUserDO::getEmailPwd, loginRequest.getPassword());
                break;
            case MOBILE:
                authUserDO.setMobile(loginRequest.getAccount());
                authUserDO.setMobilePassword(loginRequest.getPassword());

                queryWrapper.eq(AuthUserDO::getMobile, loginRequest.getAccount());
                queryWrapper.eq(AuthUserDO::getMobilePassword, loginRequest.getPassword());
                break;
            default:
                throw new AccountException("1111", "账号类型不匹配-type=[{0}]", loginRequest.getType());

        }


        AuthUserDO result = this.authUserMapper.selectOne(queryWrapper);
        if (Objects.isNull(result)) {
            throw new AccountException("1111", "请输入正确的账号和密码", null);
        }
        LoginModel loginModel = new LoginModel();
        try {
            loginModel.setToken(URLEncoder.encode(AesEncodeUtil.encrypt(JSONObject.toJSONString(result)), Charset.defaultCharset().toString()));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return loginModel;
    }

}
